package com.zjut.spider;

import com.alibaba.fastjson.JSON;
import com.zjut.VO.HitVO;
import com.zjut.pojo.CurrentHitList;
import com.zjut.pojo.Product;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Selectable;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by Ryan on 2016/10/25.
 */
public class JDDBDProcessor implements PageProcessor {

    private static Logger logger = Logger.getLogger(JDDBDProcessor.class);

    private static final String URL_BASE = "http://dbditem.jd.com/";
    private static final String START = "10002130";
    public static final String URL_FIRST = "http://dbditem.jd.com/" + START;
    private static final String END = "10002131";
    private static final String YYYYMMDD_HHMMSS = "yyyy-MM-dd HH:mm:ss";

    private AtomicInteger count = new AtomicInteger(Integer.parseInt(START));

    private Site site = Site
            .me()
            .setDomain("URL_BASE")
            .setSleepTime(200)
            .setUserAgent(
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31");

    public JDDBDProcessor() {
    }

    public Object getAjaxObject(HttpGet getURL, Object clazz) throws Exception {
        CloseableHttpClient httpclient = HttpClientBuilder.create().build();
        org.apache.http.client.methods.HttpGet httpGet = new org.apache.http.client.methods.HttpGet(getURL.buildUrl());

        //配置请求的超时设置
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(50)
                .setConnectTimeout(50)
                .setSocketTimeout(50).build();
        httpGet.setConfig(requestConfig);
        httpGet.setHeader("Referer", "http://dbditem.jd.com/"+getURL.getDBDid());
        httpGet.setHeader("Cookie", "__jdv=122270672|direct|-|none|-|1477489134497; __jda=122270672.1753615286.1477489134.1477489134.1477489134.1; __jdb=122270672.2.1753615286|1.1477489134; __jdc=122270672");

        CloseableHttpResponse response = httpclient.execute(httpGet);
//        System.out.println("StatusCode -> " + response.getStatusLine().getStatusCode());
        if (response.getStatusLine().getStatusCode()!=200){
            throw new Exception("AJAX Exception");
        }
        HttpEntity entity = response.getEntity();
        String jsonStr = EntityUtils.toString(entity, "utf-8");
        CurrentHitList currentHitList= JSON.parseObject(jsonStr, clazz.getClass().class);
        System.out.println(jsonStr);
        httpGet.releaseConnection();
        return currentHitList;
    }

    @Override
    public void process(Page page) {
        try {
            while (page.getTargetRequests().size() < 4) {
                int num = count.addAndGet(1);
                String s = BigDecimal.valueOf(num).toString();
                if (s.compareTo(END) < 0) {
                    page.addTargetRequest(URL_BASE + s);
                } else break;
            }
            System.out.println(page);
            HttpGet getURL = new HttpGet("http://dbditem.jd.com/json/current/englishquery");
            getURL.addParameter("paimaiId", page.getUrl().toString().substring(22));
            getURL.addParameter("skuId", "0");
            getURL.addParameter("t", String.format("%04d", new Random().nextInt(1000000)));
            getURL.addParameter("start", "0");
            getURL.addParameter("end", "1");
            getURL.setDBDid(page.getUrl().toString().substring(22));

            CurrentHitList currentHitList = (CurrentHitList)getAjaxObject(getURL);

            Selectable auction2 = page.getHtml().xpath("//div[@class='product_intro']/div[@class='intro_detail']/div[@class='auction2']");
            Selectable cost = auction2.xpath("//div[@class='auction_intro']/div[@class='cost']");
            Selectable endTime = auction2.xpath("//div[@class='auction_intro']/div[@class='intro_timer']/span[@class='color33']");

            Selectable details_sidebar = page.getHtml().xpath("//div[@class='details_sidebar']/div[@class='details_column wide']/div[@class='records']/dl");
            Selectable hitTime = details_sidebar.xpath("//dd//span[@class='wd1']").regex("1\">(.*)</span>");
            Selectable hiterPhone = details_sidebar.xpath("//dd//span[@class='wd2']//i[@class='phone']").regex("phone\">(.*)</i>");
            Selectable hiterPrice = details_sidebar.xpath("//dd//span[@class='wd2']//i[@class='price']").regex("￥(.*)</i>");
            Selectable hiterPriceResult = details_sidebar.xpath("//dd//span[@class='wd3']").regex("<i>(.*)</i>");

            Selectable productName = page.getHtml().xpath("//div[@class='product_intro']/div[@class='intro_detail']/div[@class='name']/@title");
            if (StringUtils.isEmpty(productName.toString())) {
                throw new Exception("产品名不存在，页面可能不存在");
            }
            Selectable productUsingInfo = page.getHtml().xpath("//div[@class='product_intro']/div[@class='intro_detail']/div[@class='name']/h1/i/@class").regex(" (.*)");
            Selectable productLink = page.getHtml().xpath("//div[@class='menu_tab clearfix']/a/@href");
            Selectable productJDID = page.getHtml().xpath("//div[@class='menu_tab clearfix']/a/@href").regex("http://item.jd.com/(.*).html");
            Selectable productDbID = page.getHtml().xpath("//div[@class='tabContent product_detail_1']/div/p").regex("夺宝岛编号：</span>(.*)</p>");
            Selectable productAppearance = page.getHtml().xpath("//div[@class='tabContent product_detail_1']/div/p").regex("包装外观：</span>(.*)</p>");
            Selectable productLocale = page.getHtml().xpath("//div[@class='tabContent product_detail_1']/div/p").regex("商品所在地：</span>(.*)</p>");
            Selectable productAttachmentList = page.getHtml().xpath("//div[@class='tabContent product_detail_1']/div/div//em").regex("<em>(.*)<");
            Selectable watchedTimes = cost.regex("font14\">(.*)次</span>");
            Selectable endTimeSelectable = endTime.regex("olor33\">(.*)</span>");
            Selectable topPrice = cost.regex("封顶价：¥(.*) \\s");
            Selectable currentPrice = cost.regex("¥</em>(.*)</span>");


            Product product = new Product();
            product.setPageAddr(page.getUrl().toString());
            product.setProductName(productName.toString());
            product.setProductUsingInfo(productUsingInfo.toString());
            product.setProductLink(productLink.toString());
            product.setProductJdId(productJDID.toString());
            product.setProductDbdId(productDbID.toString());
            product.setProductAppearanceInfo(productAppearance.toString());
            product.setProductLocale(productLocale.toString());
            product.setProductAttachmentList(productAttachmentList.toString());
            product.setWatchedTimes(new Integer(watchedTimes.toString()));
            SimpleDateFormat formatter = new SimpleDateFormat(YYYYMMDD_HHMMSS);
            try {
                product.setEndTime(formatter.parse(endTimeSelectable.toString()));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            if (StringUtils.isNotEmpty(topPrice.toString())) {
                product.setTopPrice(new BigDecimal(topPrice.toString()));
            }
            product.setCurrentPrice(new BigDecimal(currentPrice.toString()));
            product.setCreateTime(new Date());
            if (StringUtils.isNotEmpty(topPrice.toString())) {
                product.setDiscount(new BigDecimal(new Float(currentPrice.toString()) / new Float(topPrice.toString())));
            }

            List<HitVO> hitVOList = new ArrayList<HitVO>();
            for (int i = 0; i < hitTime.all().size(); i++) {
                HitVO hitVO = new HitVO();
                String hitTimeString = hitTime.all().get(i);
                try {
                    hitVO.setHitTime(formatter.parse(hitTimeString));
                } catch (ParseException e) {
                    logger.debug(hitTimeString + "：HitTime时间转换异常\n", e);
                }

                hitVO.setHiterPhone(hiterPhone.all().get(i));
                hitVO.setHiterPrice(new BigDecimal(hiterPrice.all().get(i)));
                hitVO.setHiterPriceResult(hiterPriceResult.all().get(i));
                hitVOList.add(hitVO);
            }
            String hitVOListJsonText = JSON.toJSONStringWithDateFormat(hitVOList, "yy-MM-dd HH:mm:ss");
            product.setHitInfo(hitVOListJsonText);
            page.putField("Product", product);
        } catch (Exception e) {
            logger.error(page.getUrl().toString() + "数据处理出错", e);
        }
    }

    @Override
    public Site getSite() {
        return site;
    }
}
